﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace KDSugar.Galaxy.API
{
    /// <summary>
    /// 星空云API接口调用类
    /// </summary>
    public class GalaxyCloudAPIClient
    {

        /// <summary>
        /// 客户端所在路径
        /// </summary>
        public string ClientUrl { get; private set; }

        #region 登录验证信息
        /// <summary>
        /// 账套Id
        /// </summary>
        public string AcctId { get; private set; }

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; private set; }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; private set; }

        /// <summary>
        /// 语言
        /// </summary>
        public Constant.LanguageTypeEnum Language { get; private set; }
        #endregion

        /// <summary>
        /// 初始化API接口调用类
        /// </summary>
        /// <param name="_url">URL</param>
        /// <param name="_acctId">账套ID</param>
        /// <param name="_user">用户名</param>
        /// <param name="_pass">密码</param>
        /// <param name="_lang">语言（默认简体中文）</param>
        public GalaxyCloudAPIClient(string _url,string _acctId,string _user,string _pass,
            Constant.LanguageTypeEnum _lang = Constant.LanguageTypeEnum.CHS)
        {
            ClientUrl = _url;
            AcctId = _acctId;
            UserName = _user;
            Password = _pass;
            Language = _lang;
        }

        /// <summary>
        /// 客户端Cookie
        /// </summary>
        public CookieContainer Cookie { get; private set; } = new CookieContainer();

        /// <summary>
        /// 登录验证是否成功
        /// </summary>
        public bool IsLogin
        {
            get
            {
                bool result = false;
                if (LoginResponseContent != null)
                {
                    if (LoginResponseContent.LoginResultTypeStatus == LoginResponseInfo.LoginResultTypeStatusEnum.Success ||
                        LoginResponseContent.LoginResultTypeStatus == LoginResponseInfo.LoginResultTypeStatusEnum.DealWithForm)
                        result = true;
                }
                return result;
            }
        }

        /// <summary>
        /// 登录返回信息
        /// </summary>
        public string LoginMessage
        {
            get
            {
                string result = null;
                if (LoginResponseContent != null)
                    result = LoginResponseContent.Message;
                return result;
            }
        }

        /// <summary>
        /// 登录返回码枚举
        /// </summary>
        public LoginResponseInfo.LoginResultTypeStatusEnum LoginResultTypeStatus
        {
            get
            {
                LoginResponseInfo.LoginResultTypeStatusEnum result = LoginResponseInfo.LoginResultTypeStatusEnum.UNKNOW;
                if (LoginResponseContent != null)
                    result = LoginResponseContent.LoginResultTypeStatus;
                return result;
            }
        }

        /// <summary>
        /// 登录返回码
        /// </summary>
        public long? LoginResultTypeCode
        {
            get
            {
                long? result = null;
                if (LoginResponseContent != null)
                    result = LoginResponseContent.LoginResultType;
                return result;
            }
        }

        /// <summary>
        /// 登录返回信息
        /// </summary>
        public LoginResponseInfo LoginResponseContent { get; private set; }

        /// <summary>
        /// 登录验证
        /// </summary>
        /// <param name="_isKickOff">是否踢人，默认不踢人</param>
        public LoginResponseInfo Login(bool _isKickOff = false)
        {
            LoginResponseInfo result = null;
            string loginUrl = _isKickOff ? "/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser2.common.kdsvc" :
                "/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc";
            string tmpUrl = ClientUrl + loginUrl;
            List<object> para = new List<object>();
            para.Add(AcctId);
            para.Add(UserName);
            para.Add(Password);
            para.Add(Language);
            string tmpContent = JsonConvert.SerializeObject(para);
            string tmpResult = ExecuteCommand(tmpUrl, tmpContent);
            LoginResponseContent = JsonConvert.DeserializeObject<LoginResponseInfo>(tmpResult);
            result = LoginResponseContent;
            //IsLogin = true;
            return result;
        }

        /// <summary>
        /// 执行指令
        /// </summary>
        /// <typeparam name="T">指令基类</typeparam>
        /// <param name="t">指令</param>
        /// <returns>执行数据</returns>
        public ExecuteDataInfo ExecuteCommand<T>(T t) where T : Base.BaseCommand
        {
            ExecuteDataInfo result = new ExecuteDataInfo();
            if (t != null && IsLogin)
            {
                string tmpRequestUrl = ClientUrl + t.CommandUrl;
                string tmpContent = t.BuildRequestContent();
                result.RequestData = tmpContent;
                result.ResponseData = ExecuteCommand(tmpRequestUrl, tmpContent);
            }
            return result;
        }

        /// <summary>
        /// 执行指令（简易模式）
        /// </summary>
        /// <param name="_url">指令地址</param>
        /// <param name="_content">请求内容</param>
        /// <returns>返回数据</returns>
        public string ExecuteCommand(string _url,string _content)
        {
            string result = null;
            if (!string.IsNullOrWhiteSpace(_content) && !string.IsNullOrWhiteSpace(_url))
            {
                HttpWebRequest webRequest = HttpWebRequest.Create(_url) as HttpWebRequest;
                webRequest.Method = "POST";
                webRequest.ContentType = "application/json";
                webRequest.CookieContainer = Cookie;
                webRequest.Timeout = GlobalSetting.RequestTimeout;
                using (Stream stream = webRequest.GetRequestStream())
                {
                    JObject obj = new JObject();
                    obj.Add("format", 1);
                    obj.Add("useragent", "ApiClient");
                    obj.Add("rid", Guid.NewGuid().ToString().GetHashCode().ToString());
                    obj.Add("parameters", _content);
                    obj.Add("timestamp", DateTime.Now);
                    obj.Add("v", "1.0");
                    string sContent = obj.ToString();
                    var bytes = Encoding.UTF8.GetBytes(sContent);
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Flush();
                }
                using (Stream stream = webRequest.GetResponse().GetResponseStream())
                {
                    using (StreamReader sr = new StreamReader(stream))
                    {
                        result = ValidateResult(sr.ReadToEnd());
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 验证错误信息
        /// </summary>
        /// <param name="_content"></param>
        /// <returns></returns>
        private string ValidateResult(string _content)
        {
            string result = _content;
            if (result.StartsWith("response_error:"))
                result = result.TrimStart("response_error:".ToCharArray());
            return result;
        }

        /// <summary>
        /// 登录返回信息类
        /// </summary>
        public class LoginResponseInfo
        {
            /// <summary>
            /// 消息
            /// </summary>
            public string Message { get; set; }

            /// <summary>
            /// 消息码
            /// </summary>
            public string MessageCode { get; set; }

            /// <summary>
            /// 登录返回码
            /// </summary>
            public long LoginResultType { get; set; } = -65535;

            /// <summary>
            /// 登录返回码对应状态
            /// </summary>
            [JsonIgnore]
            public LoginResultTypeStatusEnum LoginResultTypeStatus
            {
                get
                {
                    LoginResultTypeStatusEnum reslt = LoginResultTypeStatusEnum.UNKNOW;
                    switch (LoginResultType)
                    {
                        case -7:
                            reslt = LoginResultTypeStatusEnum.Activation;
                            break;
                        case -6:
                            reslt = LoginResultTypeStatusEnum.EntryCloudUnBind;
                            break;
                        case -5:
                            reslt = LoginResultTypeStatusEnum.DealWithForm;
                            break;
                        case -4:
                            reslt = LoginResultTypeStatusEnum.Wanning;
                            break;
                        case -3:
                            reslt = LoginResultTypeStatusEnum.PWInvalid_Required;
                            break;
                        case -2:
                            reslt = LoginResultTypeStatusEnum.PWInvalid_Optional;
                            break;
                        case -1:
                            reslt = LoginResultTypeStatusEnum.Failure;
                            break;
                        case 0:
                            reslt = LoginResultTypeStatusEnum.PWError;
                            break;
                        case 1:
                            reslt = LoginResultTypeStatusEnum.Success;
                            break;
                        default:
                            reslt = LoginResultTypeStatusEnum.UNKNOW;
                            break;
                    }
                    return reslt;
                }
            }

            /// <summary>
            /// 登录返回码对应状态枚举
            /// </summary>
            public enum LoginResultTypeStatusEnum
            {
                /// <summary>
                /// 激活
                /// </summary>
                Activation,
                /// <summary>
                /// 云通行证未绑定Cloud账号
                /// </summary>
                EntryCloudUnBind,
                /// <summary>
                /// 需要表单处理
                /// </summary>
                DealWithForm,
                /// <summary>
                /// 登录警告
                /// </summary>
                Wanning,
                /// <summary>
                /// 密码验证不通过（强制的）
                /// </summary>
                PWInvalid_Required,
                /// <summary>
                /// 密码验证不通过（可选的）
                /// </summary>
                PWInvalid_Optional,
                /// <summary>
                /// 登录失败
                /// </summary>
                Failure,
                /// <summary>
                /// 用户或密码错误
                /// </summary>
                PWError,
                /// <summary>
                /// 登录成功
                /// </summary>
                Success,
                /// <summary>
                /// 未知
                /// </summary>
                UNKNOW
            }

            /// <summary>
            /// 上下文
            /// </summary>
            public object Context { get; set; }

            /// <summary>
            /// SessionId
            /// </summary>
            public string KDSVCSessionId { get; set; }

            /// <summary>
            /// LCID
            /// </summary>
            public long Lcid { get; set; }

            /// <summary>
            /// 其他信息
            /// </summary>
            [JsonExtensionData]
            public Dictionary<string,object> OtherInfo { get; set; }
        }
    }
}
